ποΈGitΠ―ΡΠ°ποΈ
docs/nrf52_power_management.md 890a2e2cffa98dea3ca88db3c3aba72ef23ff3f7 (890a2e2c) Text, 10.89 KB
nRF52 Power Management
Overview
The nRF52 Power Management module provides battery protection features to prevent over-discharge, minimise likelihood of brownout and flash corruption conditions existing, and enable safe voltage-based recovery.
Features
Boot Voltage Protection
β’ Checks battery voltage immediately after boot and before mesh operations commence
β’ If voltage is below a configurable threshold (e.g., 3300mV), the device configures voltage wake (LPCOMP + VBUS) and enters protective shutdown (SYSTEMOFF)
β’ Prevents boot loops when battery is critically low
β’ Skipped when external power (USB VBUS) is detected
Voltage Wake (LPCOMP + VBUS)
β’ Configures the nRF52's Low Power Comparator (LPCOMP) before entering SYSTEMOFF
β’ Enables USB VBUS detection so external power can wake the device
β’ Device automatically wakes when battery voltage rises above recovery threshold or when VBUS is detected
Early Boot Register Capture
β’ Captures RESETREAS (reset reason) and GPREGRET2 (shutdown reason) before SystemInit() clears them
β’ Allows firmware to determine why it booted (cold boot, watchdog, LPCOMP wake, etc.)
β’ Allows firmware to determine why it last shut down (user request, low voltage, boot protection)
Shutdown Reason Tracking
Shutdown reason codes (stored in GPREGRET2):
ββββββββ¬βββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β Code β Name β Description β
ββββββββΌβββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ€
β 0x00 β NONE β Normal boot / no previous shutdown β
β 0x4C β LOW_VOLTAGE β Runtime low voltage threshold reached β
β 0x55 β USER β User requested powerOff() β
β 0x42 β BOOT_PROTECT β Boot voltage protection triggered β
ββββββββ΄βββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββ
Supported Boards
βββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββ¬ββββββββββββββ¬ββββββββββββ
β Board β Implemented β LPCOMP wake β VBUS wake β
βββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββΌββββββββββββββΌββββββββββββ€
β Seeed Studio XIAO nRF52840 (T383838xiao_nrf52) β Yes β Yes β Yes β
β RAK4631 (T383838rak4631) β Yes β Yes β Yes β
β Heltec T114 (T383838heltec_t114) β Yes β Yes β Yes β
β GAT562 Mesh Watch13 β Yes β Yes β Yes β
β Promicro nRF52840 β No β No β No β
β RAK WisMesh Tag β No β No β No β
β Heltec Mesh Solar β No β No β No β
β LilyGo T-Echo / T-Echo Lite β No β No β No β
β SenseCAP Solar β Yes β Yes β Yes β
β WIO Tracker L1 / L1 E-Ink β No β No β No β
β WIO WM1110 β No β No β No β
β Mesh Pocket β No β No β No β
β Nano G2 Ultra β No β No β No β
β ThinkNode M1/M3/M6 β No β No β No β
β T1000-E β No β No β No β
β Ikoka Nano/Stick/Handheld (nRF) β No β No β No β
β Keepteen LT1 β No β No β No β
β Minewsemi ME25LS01 β No β No β No β
βββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββ΄ββββββββββββββ΄ββββββββββββ
Notes:
β’ "Implemented" reflects Phase 1 (boot lockout + shutdown reason capture).
β’ User power-off on Heltec T114 does not enable LPCOMP wake.
β’ VBUS detection is used to skip boot lockout on external power, and VBUS wake is configured alongside LPCOMP when supported hardware exposes VBUS to the nRF52.
Technical Details
Architecture
The power management functionality is integrated into the T383838NRF52Board base class in T383838src/helpers/NRF52Board.cpp. Board variants provide hardware-specific configuration via a T383838PowerMgtConfig struct and override T383838initiateShutdown(uint8_t reason) to perform board-specific power-down work and conditionally enable voltage wake (LPCOMP + VBUS).
Early Boot Capture
A static constructor with priority 101 in T383838NRF52Board.cpp captures the RESETREAS and GPREGRET2 registers before:
β’ SystemInit() (priority 102) - which clears RESETREAS
β’ Static C++ constructors (default priority 65535)
This ensures we capture the true reset reason before any initialisation code runs.
Board Implementation
To enable power management on a board variant:
1. Enable in platformio.ini:
T282828
Te6edf3-D NRF52_POWER_MANAGEMENT
2. Define configuration in variant.h:
T282828
Tff7b72#Tff7b72define PWRMGT_VOLTAGE_BOOTLOCK 3300 T8b949e// Won't boot below this voltage (mV)
Tff7b72#Tff7b72define PWRMGT_LPCOMP_AIN 7 T8b949e// AIN channel for voltage sensing
Tff7b72#Tff7b72define PWRMGT_LPCOMP_REFSEL 2 T8b949e// REFSEL (0-6=1/8..7/8, 7=ARef, 8-15=1/16..15/16)
3. Implement in board .cpp file:
T282828
Tff7b72#Tff7b72ifdef NRF52_POWER_MANAGEMENT
Tff7b72const Te6edf3PowerMgtConfig Te6edf3power_config Tff7b72= Tb4b4b4{
Tb4b4b4.Te6edf3lpcomp_ain_channel Tff7b72= Te6edf3PWRMGT_LPCOMP_AINTb4b4b4,
Tb4b4b4.Te6edf3lpcomp_refsel Tff7b72= Te6edf3PWRMGT_LPCOMP_REFSELTb4b4b4,
Tb4b4b4.Te6edf3voltage_bootlock Tff7b72= Te6edf3PWRMGT_VOLTAGE_BOOTLOCK
Tb4b4b4}Tb4b4b4;
Tffa657void Td2a8ffMyBoard::initiateShutdownTb4b4b4(Tffa657uint8_t Te6edf3reasonTb4b4b4) Tb4b4b4{
T8b949e// Board-specific shutdown preparation (e.g., disable peripherals)
Tffa657bool Te6edf3enable_lpcomp Tff7b72= Tb4b4b4(Te6edf3reason Tff7b72=Tff7b72= Te6edf3SHUTDOWN_REASON_LOW_VOLTAGE Tff7b72|Tff7b72|
Te6edf3reason Tff7b72=Tff7b72= Te6edf3SHUTDOWN_REASON_BOOT_PROTECTTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3enable_lpcompTb4b4b4) Tb4b4b4{
Te6edf3configureVoltageWakeTb4b4b4(Te6edf3power_configTb4b4b4.Te6edf3lpcomp_ain_channelTb4b4b4, Te6edf3power_configTb4b4b4.Te6edf3lpcomp_refselTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3enterSystemOffTb4b4b4(Te6edf3reasonTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tffa657void Td2a8ffMyBoard::beginTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3NRF52BoardTff7b72:Tff7b72:Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// or NRF52BoardDCDC::begin()
T8b949e// ... board setup ...
Tff7b72#Tff7b72ifdef NRF52_POWER_MANAGEMENT
Te6edf3checkBootVoltageTb4b4b4(Tff7b72&Te6edf3power_configTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
For user-initiated shutdowns, T383838powerOff() remains board-specific. Power management only arms LPCOMP for automated shutdown reasons (boot protection/low voltage).
4. Declare override in board .h file:
T282828
Tff7b72#Tff7b72ifdef NRF52_POWER_MANAGEMENT
Tffa657void Td2a8ffinitiateShutdownTb4b4b4(Tffa657uint8_t Te6edf3reasonTb4b4b4) Tff7b72overrideTb4b4b4;
Tff7b72#Tff7b72endif
Voltage Wake Configuration
The LPCOMP (Low Power Comparator) is configured to:
β’ Monitor the specified AIN channel (0-7 corresponding to P0.02-P0.05, P0.28-P0.31)
β’ Compare against VDD fraction reference (REFSEL: 0-6=1/8..7/8, 7=ARef, 8-15=1/16..15/16)
β’ Detect UP events (voltage rising above threshold)
β’ Use 50mV hysteresis for noise immunity
β’ Wake the device from SYSTEMOFF when triggered
VBUS wake is enabled via the POWER peripheral USBDETECTED event whenever T383838configureVoltageWake() is used. This requires USB VBUS to be routed to the nRF52 (typical on nRF52840 boards with native USB).
LPCOMP Reference Selection (PWRMGTLPCOMPREFSEL):
ββββββββββ¬βββββββββββ¬βββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β REFSEL β Fraction β VBAT @ 1M/1M divider (VDD=3.0-3.3) β VBAT @ 1.5M/1M divider (VDD=3.0-3.3) β
ββββββββββΌβββββββββββΌβββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ€
β 0 β 1/8 β 0.75-0.82 V β 0.94-1.03 V β
β 1 β 2/8 β 1.50-1.65 V β 1.88-2.06 V β
β 2 β 3/8 β 2.25-2.47 V β 2.81-3.09 V β
β 3 β 4/8 β 3.00-3.30 V β 3.75-4.12 V β
β 4 β 5/8 β 3.75-4.12 V β 4.69-5.16 V β
β 5 β 6/8 β 4.50-4.95 V β 5.62-6.19 V β
β 6 β 7/8 β 5.25-5.77 V β 6.56-7.22 V β
β 7 β ARef β - β - β
β 8 β 1/16 β 0.38-0.41 V β 0.47-0.52 V β
β 9 β 3/16 β 1.12-1.24 V β 1.41-1.55 V β
β 10 β 5/16 β 1.88-2.06 V β 2.34-2.58 V β
β 11 β 7/16 β 2.62-2.89 V β 3.28-3.61 V β
β 12 β 9/16 β 3.38-3.71 V β 4.22-4.64 V β
β 13 β 11/16 β 4.12-4.54 V β 5.16-5.67 V β
β 14 β 13/16 β 4.88-5.36 V β 6.09-6.70 V β
β 15 β 15/16 β 5.62-6.19 V β 7.03-7.73 V β
ββββββββββ΄βββββββββββ΄βββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββ
Important: For boards with a voltage divider on the battery sense pin, LPCOMP measures the divided voltage. Use:
T383838VBAT_threshold β (VDD * fraction) * divider_scale, where T383838divider_scale = (Rtop + Rbottom) / Rbottom (e.g., 2.0 for 1M/1M, 2.5 for 1.5M/1M, 3.0 for XIAO).
SoftDevice Compatibility
The power management code checks whether SoftDevice is enabled and uses the appropriate API:
β’ When SD enabled: T383838sd_power_* functions
β’ When SD disabled: Direct register access (NRF_POWER->*)
This ensures compatibility regardless of BLE stack state.
CLI Commands
Power management status can be queried via the CLI:
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Command β Description β
βββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β T383838get pwrmgt.support β Returns "supported" or "unsupported" β
β T383838get pwrmgt.source β Returns current power source - "battery" or "external" (5V/USB power) β
β T383838get pwrmgt.bootreason β Returns reset and shutdown reason strings β
β T383838get pwrmgt.bootmv β Returns boot voltage in millivolts β
βββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
On boards without power management enabled, all commands except T383838get pwrmgt.support return:
T282828
ERROR: Power management not supported
Debug Output
When T383838MESH_DEBUG=1 is enabled, the power management module outputs:
T282828
DEBUG: PWRMGT: Reset = Wake from LPCOMP (0x20000); Shutdown = Low Voltage (0x4C)
DEBUG: PWRMGT: Boot voltage = 3450 mV (threshold = 3300 mV)
DEBUG: PWRMGT: LPCOMP wake configured (AIN7, ref=3/8 VDD)
Phase 2 (Planned)
β’ Runtime voltage monitoring
β’ Voltage state machine (Normal -> Warning -> Critical -> Shutdown)
β’ Configurable thresholds
β’ Load shedding callbacks for power reduction
β’ Deep sleep integration
β’ Scheduled wake-up
β’ Extended sleep with periodic monitoring
References
Served by rngit 1.5.2 - Generated in 0.07s